# Draw a sheet containing scales for estimating sizes of distant objects
# or measuring their angular extent.
#
# Eye measurements in cm:
#   dp    65
#   gp    55.9
#
###########################################################################
 
from __future__ import division
import sys
from g import *
from math import sin, cos, tan, pi, sqrt, atan
from versiondec import VersionDec as vd
from pdb import set_trace as xx

debug = 0

wrap_in_PJL = 0
d2r = pi/180
cm2in = 1/2.54

t0, t1, t2, t3 = 0.5, 0.75, 1.25, 2
mark_dict = {
    # key is eye distance in cm
    # value is (location_point, num_tenth_degrees, marks)
    # marks is (factor, label_string, tick_length, text_height_factor)

    "52.5" : ((0, 0), 89,
        (
        ( 7,    "x7",    t1, 1),
        (7.5,   "",      t0, 1),
        ( 8,    "x8",    t1, 1),
        (8.5,   "",      t0, 1),
        ( 9,    "x9",    t1, 1),
        (9.5,   "",      t0, 1),
        (10,    "x10",   t3, 1),
        (11,    "",      t1, 1),
        (12,    "x12",   t1, 1),
        (13,    "",      t1, 1),
        (14,    "",      t1, 1),
        (15,    "x15",   t2, 1),
        (16,    "",      t1, 1),
        (17,    "",      t1, 1),
        (18,    "",      t1, 1),
        (19,    "",      t1, 1),
        (20,    "x20",   t3, 1),
        (21,    "",      t1, 1),
        (22,    "",      t1, 1),
        (23,    "",      t1, 1),
        (24,    "",      t1, 1),
        (25,    "x25",   t2, 1),
        (26,    "",      t1, 1),
        (27,    "",      t1, 1),
        (28,    "",      t1, 1),
        (29,    "",      t1, 1),
        (30,    "x30",   t3, 1),
        (31,    "",      t1, 1),
        (32,    "",      t1, 1),
        (33,    "",      t1, 1),
        (34,    "",      t1, 1),
        (35,    "",      t2, 1),
        (36,    "",      t1, 1),
        (37,    "",      t1, 1),
        (38,    "",      t1, 1),
        (39,    "",      t1, 1),
        (40,    "x40",   t3, 1),
        (45,    "",      t1, 1),
        (50,    "x50",   t3, 0.9),
        (60,    "",      t1, 1),
        (70,    "",      t1, 1),
        (80,    "",      t1, 1),
        (90,    "",      t1, 1),
        (100,   "x100",  t3, 1),
        (150,   "",      t2, 1),
        (200,   "x200",  t3, 0.7),
        (500,   "x500",  t3, 0.5),
        ),
    ), 

    "55" : ((1, 0), 84,
        (
        ( 7,    "x7",    t1, 1),
        (7.5,   "",      t0, 1),
        ( 8,    "x8",    t1, 1),
        (8.5,   "",      t0, 1),
        ( 9,    "x9",    t1, 1),
        (9.5,   "",      t0, 1),
        (10,    "x10",   t3, 1),
        (11,    "",      t1, 1),
        (12,    "x12",   t1, 1),
        (13,    "",      t1, 1),
        (14,    "",      t1, 1),
        (15,    "x15",   t2, 1),
        (16,    "",      t1, 1),
        (17,    "",      t1, 1),
        (18,    "",      t1, 1),
        (19,    "",      t1, 1),
        (20,    "x20",   t3, 1),
        (21,    "",      t1, 1),
        (22,    "",      t1, 1),
        (23,    "",      t1, 1),
        (24,    "",      t1, 1),
        (25,    "x25",   t2, 1),
        (26,    "",      t1, 1),
        (27,    "",      t1, 1),
        (28,    "",      t1, 1),
        (29,    "",      t1, 1),
        (30,    "x30",   t3, 1),
        (31,    "",      t1, 1),
        (32,    "",      t1, 1),
        (33,    "",      t1, 1),
        (34,    "",      t1, 1),
        (35,    "",      t2, 1),
        (36,    "",      t1, 1),
        (37,    "",      t1, 1),
        (38,    "",      t1, 1),
        (39,    "",      t1, 1),
        (40,    "x40",   t3, 1),
        (45,    "",      t1, 1),
        (50,    "x50",   t3, 0.9),
        (60,    "",      t1, 1),
        (70,    "",      t1, 1),
        (80,    "",      t1, 1),
        (90,    "",      t1, 1),
        (100,   "x100",  t3, 1),
        (150,   "",      t2, 1),
        (200,   "x200",  t3, 0.7),
        (500,   "x500",  t3, 0.5),
        ),
    ), 

    "57.5" : ((2, 0), 80,
        (
        (7.5,   "7.5",   t0, 1),
        ( 8,    "x8",    t1, 1),
        (8.5,   "",      t0, 1),
        ( 9,    "x9",    t1, 1),
        (9.5,   "",      t0, 1),
        (10,    "x10",   t3, 1),
        (11,    "",      t1, 1),
        (12,    "x12",   t1, 1),
        (13,    "",      t1, 1),
        (14,    "",      t1, 1),
        (15,    "x15",   t2, 1),
        (16,    "",      t1, 1),
        (17,    "",      t1, 1),
        (18,    "",      t1, 1),
        (19,    "",      t1, 1),
        (20,    "x20",   t3, 1),
        (21,    "",      t1, 1),
        (22,    "",      t1, 1),
        (23,    "",      t1, 1),
        (24,    "",      t1, 1),
        (25,    "x25",   t2, 1),
        (26,    "",      t1, 1),
        (27,    "",      t1, 1),
        (28,    "",      t1, 1),
        (29,    "",      t1, 1),
        (30,    "x30",   t3, 1),
        (31,    "",      t1, 1),
        (32,    "",      t1, 1),
        (33,    "",      t1, 1),
        (34,    "",      t1, 1),
        (35,    "",      t2, 1),
        (36,    "",      t1, 1),
        (37,    "",      t1, 1),
        (38,    "",      t1, 1),
        (39,    "",      t1, 1),
        (40,    "x40",   t3, 1),
        (45,    "",      t1, 1),
        (50,    "x50",   t3, 0.9),
        (60,    "",      t1, 1),
        (70,    "",      t1, 1),
        (80,    "",      t1, 1),
        (90,    "",      t1, 1),
        (100,   "x100",  t3, 1),
        (150,   "",      t2, 1),
        (200,   "x200",  t3, 0.7),
        (500,   "x500",  t3, 0.5),
        ),
    ), 

    "60" : ((3, 0), 77,
        (
        ( 8,    "x8",    t1, 1),
        (8.5,   "",      t0, 1),
        ( 9,    "x9",    t1, 1),
        (9.5,   "",      t0, 1),
        (10,    "x10",   t3, 1),
        (11,    "",      t1, 1),
        (12,    "x12",   t1, 1),
        (13,    "",      t1, 1),
        (14,    "",      t1, 1),
        (15,    "x15",   t2, 1),
        (16,    "",      t1, 1),
        (17,    "",      t1, 1),
        (18,    "",      t1, 1),
        (19,    "",      t1, 1),
        (20,    "x20",   t3, 1),
        (21,    "",      t1, 1),
        (22,    "",      t1, 1),
        (23,    "",      t1, 1),
        (24,    "",      t1, 1),
        (25,    "x25",   t2, 1),
        (26,    "",      t1, 1),
        (27,    "",      t1, 1),
        (28,    "",      t1, 1),
        (29,    "",      t1, 1),
        (30,    "x30",   t3, 1),
        (31,    "",      t1, 1),
        (32,    "",      t1, 1),
        (33,    "",      t1, 1),
        (34,    "",      t1, 1),
        (35,    "",      t2, 1),
        (36,    "",      t1, 1),
        (37,    "",      t1, 1),
        (38,    "",      t1, 1),
        (39,    "",      t1, 1),
        (40,    "x40",   t3, 1),
        (45,    "",      t1, 1),
        (50,    "x50",   t3, 0.9),
        (60,    "",      t1, 1),
        (70,    "",      t1, 1),
        (80,    "",      t1, 1),
        (90,    "",      t1, 1),
        (100,   "x100",  t3, 1),
        (150,   "",      t2, 1),
        (200,   "x200",  t3, 0.7),
        (500,   "x500",  t3, 0.5),
        ),
    ), 

    "62.5" : ((4, 0), 74,
        (
        ( 8,    "x8",    t1, 1),
        (8.5,   "",      t0, 1),
        ( 9,    "x9",    t1, 1),
        (9.5,   "",      t0, 1),
        (10,    "x10",   t3, 1),
        (11,    "",      t1, 1),
        (12,    "x12",   t1, 1),
        (13,    "",      t1, 1),
        (14,    "",      t1, 1),
        (15,    "x15",   t2, 1),
        (16,    "",      t1, 1),
        (17,    "",      t1, 1),
        (18,    "",      t1, 1),
        (19,    "",      t1, 1),
        (20,    "x20",   t3, 1),
        (21,    "",      t1, 1),
        (22,    "",      t1, 1),
        (23,    "",      t1, 1),
        (24,    "",      t1, 1),
        (25,    "x25",   t2, 1),
        (26,    "",      t1, 1),
        (27,    "",      t1, 1),
        (28,    "",      t1, 1),
        (29,    "",      t1, 1),
        (30,    "x30",   t3, 1),
        (31,    "",      t1, 1),
        (32,    "",      t1, 1),
        (33,    "",      t1, 1),
        (34,    "",      t1, 1),
        (35,    "",      t2, 1),
        (36,    "",      t1, 1),
        (37,    "",      t1, 1),
        (38,    "",      t1, 1),
        (39,    "",      t1, 1),
        (40,    "x40",   t3, 1),
        (45,    "",      t1, 1),
        (50,    "x50",   t3, 0.9),
        (60,    "",      t1, 1),
        (70,    "",      t1, 1),
        (80,    "",      t1, 1),
        (90,    "",      t1, 1),
        (100,   "x100",  t3, 1),
        (150,   "",      t2, 1),
        (200,   "x200",  t3, 0.7),
        (500,   "x500",  t3, 0.5),
        ),
    ), 

    "65" : ((0, 1), 72,
        (
        (8.5,   "8.5",   t0, 1),
        ( 9,    "x9",    t1, 1),
        (9.5,   "",      t0, 1),
        (10,    "x10",   t3, 1),
        (11,    "",      t1, 1),
        (12,    "x12",   t1, 1),
        (13,    "",      t1, 1),
        (14,    "",      t1, 1),
        (15,    "x15",   t2, 1),
        (16,    "",      t1, 1),
        (17,    "",      t1, 1),
        (18,    "",      t1, 1),
        (19,    "",      t1, 1),
        (20,    "x20",   t3, 1),
        (21,    "",      t1, 1),
        (22,    "",      t1, 1),
        (23,    "",      t1, 1),
        (24,    "",      t1, 1),
        (25,    "x25",   t2, 1),
        (26,    "",      t1, 1),
        (27,    "",      t1, 1),
        (28,    "",      t1, 1),
        (29,    "",      t1, 1),
        (30,    "x30",   t3, 1),
        (31,    "",      t1, 1),
        (32,    "",      t1, 1),
        (33,    "",      t1, 1),
        (34,    "",      t1, 1),
        (35,    "",      t2, 1),
        (36,    "",      t1, 1),
        (37,    "",      t1, 1),
        (38,    "",      t1, 1),
        (39,    "",      t1, 1),
        (40,    "x40",   t3, 1),
        (45,    "",      t1, 1),
        (50,    "x50",   t3, 1),
        (60,    "",      t1, 1),
        (70,    "",      t1, 1),
        (80,    "",      t1, 1),
        (90,    "",      t1, 1),
        (100,   "x100",  t3, 1),
        (150,   "",      t2, 1),
        (200,   "x200",  t3, 0.8),
        (500,   "x500",  t3, 0.6),
        ),
    ), 

    "67.5" : ((1, 1), 68,
        (
        ( 9,    "x9",    t1, 1),
        (9.5,   "",      t0, 1),
        (10,    "x10",   t3, 1),
        (11,    "",      t1, 1),
        (12,    "x12",   t1, 1),
        (13,    "",      t1, 1),
        (14,    "",      t1, 1),
        (15,    "x15",   t2, 1),
        (16,    "",      t1, 1),
        (17,    "",      t1, 1),
        (18,    "",      t1, 1),
        (19,    "",      t1, 1),
        (20,    "x20",   t3, 1),
        (21,    "",      t1, 1),
        (22,    "",      t1, 1),
        (23,    "",      t1, 1),
        (24,    "",      t1, 1),
        (25,    "x25",   t2, 1),
        (26,    "",      t1, 1),
        (27,    "",      t1, 1),
        (28,    "",      t1, 1),
        (29,    "",      t1, 1),
        (30,    "x30",   t3, 1),
        (31,    "",      t1, 1),
        (32,    "",      t1, 1),
        (33,    "",      t1, 1),
        (34,    "",      t1, 1),
        (35,    "",      t2, 1),
        (36,    "",      t1, 1),
        (37,    "",      t1, 1),
        (38,    "",      t1, 1),
        (39,    "",      t1, 1),
        (40,    "x40",   t3, 1),
        (45,    "",      t1, 1),
        (50,    "x50",   t3, 0.9),
        (60,    "",      t1, 1),
        (70,    "",      t1, 1),
        (80,    "",      t1, 1),
        (90,    "",      t1, 1),
        (100,   "x100",  t3, 1),
        (150,   "",      t2, 1),
        (200,   "x200",  t3, 0.7),
        (500,   "x500",  t3, 0.5),
        ),
    ), 

    "70" : ((2, 1), 66,
        (
        ( 9,    "x9",    t1, 1),
        (9.5,   "",      t0, 1),
        (10,    "x10",   t3, 1),
        (11,    "",      t1, 1),
        (12,    "x12",   t1, 1),
        (13,    "",      t1, 1),
        (14,    "",      t1, 1),
        (15,    "x15",   t2, 1),
        (16,    "",      t1, 1),
        (17,    "",      t1, 1),
        (18,    "",      t1, 1),
        (19,    "",      t1, 1),
        (20,    "x20",   t3, 1),
        (21,    "",      t1, 1),
        (22,    "",      t1, 1),
        (23,    "",      t1, 1),
        (24,    "",      t1, 1),
        (25,    "x25",   t2, 1),
        (26,    "",      t1, 1),
        (27,    "",      t1, 1),
        (28,    "",      t1, 1),
        (29,    "",      t1, 1),
        (30,    "x30",   t3, 1),
        (31,    "",      t1, 1),
        (32,    "",      t1, 1),
        (33,    "",      t1, 1),
        (34,    "",      t1, 1),
        (35,    "",      t2, 1),
        (36,    "",      t1, 1),
        (37,    "",      t1, 1),
        (38,    "",      t1, 1),
        (39,    "",      t1, 1),
        (40,    "x40",   t3, 1),
        (45,    "",      t1, 1),
        (50,    "x50",   t3, 0.9),
        (60,    "",      t1, 1),
        (70,    "",      t1, 1),
        (80,    "",      t1, 1),
        (90,    "",      t1, 1),
        (100,   "x100",  t3, 1),
        (150,   "",      t2, 1),
        (200,   "x200",  t3, 0.7),
        (500,   "x500",  t3, 0.5),
        ),
    ), 

    "72.5" : ((3, 1), 64,
        (
        (10,    "x10",   t3, 1),
        (11,    "",      t1, 1),
        (12,    "x12",   t1, 1),
        (13,    "",      t1, 1),
        (14,    "",      t1, 1),
        (15,    "x15",   t2, 1),
        (16,    "",      t1, 1),
        (17,    "",      t1, 1),
        (18,    "",      t1, 1),
        (19,    "",      t1, 1),
        (20,    "x20",   t3, 1),
        (21,    "",      t1, 1),
        (22,    "",      t1, 1),
        (23,    "",      t1, 1),
        (24,    "",      t1, 1),
        (25,    "x25",   t2, 1),
        (26,    "",      t1, 1),
        (27,    "",      t1, 1),
        (28,    "",      t1, 1),
        (29,    "",      t1, 1),
        (30,    "x30",   t3, 1),
        (31,    "",      t1, 1),
        (32,    "",      t1, 1),
        (33,    "",      t1, 1),
        (34,    "",      t1, 1),
        (35,    "",      t2, 1),
        (36,    "",      t1, 1),
        (37,    "",      t1, 1),
        (38,    "",      t1, 1),
        (39,    "",      t1, 1),
        (40,    "x40",   t3, 1),
        (45,    "",      t1, 1),
        (50,    "x50",   t3, 0.9),
        (60,    "",      t1, 1),
        (70,    "",      t1, 1),
        (80,    "",      t1, 1),
        (90,    "",      t1, 1),
        (100,   "x100",  t3, 1),
        (150,   "",      t2, 1),
        (200,   "x200",  t3, 0.7),
        (500,   "x500",  t3, 0.5),
        ),
    ), 

    "75" : ((4, 1), 61,
        (
        (10,    "x10",   t3, 1),
        (11,    "",      t1, 1),
        (12,    "x12",   t1, 1),
        (13,    "",      t1, 1),
        (14,    "",      t1, 1),
        (15,    "x15",   t2, 1),
        (16,    "",      t1, 1),
        (17,    "",      t1, 1),
        (18,    "",      t1, 1),
        (19,    "",      t1, 1),
        (20,    "x20",   t3, 1),
        (21,    "",      t1, 1),
        (22,    "",      t1, 1),
        (23,    "",      t1, 1),
        (24,    "",      t1, 1),
        (25,    "x25",   t2, 1),
        (26,    "",      t1, 1),
        (27,    "",      t1, 1),
        (28,    "",      t1, 1),
        (29,    "",      t1, 1),
        (30,    "x30",   t3, 1),
        (31,    "",      t1, 1),
        (32,    "",      t1, 1),
        (33,    "",      t1, 1),
        (34,    "",      t1, 1),
        (35,    "",      t2, 1),
        (36,    "",      t1, 1),
        (37,    "",      t1, 1),
        (38,    "",      t1, 1),
        (39,    "",      t1, 1),
        (40,    "x40",   t3, 1),
        (45,    "",      t1, 1),
        (50,    "x50",   t3, 0.9),
        (60,    "",      t1, 1),
        (70,    "",      t1, 1),
        (80,    "",      t1, 1),
        (90,    "",      t1, 1),
        (100,   "x100",  t3, 1),
        (150,   "",      t2, 1),
        (200,   "x200",  t3, 0.7),
        (500,   "x500",  t3, 0.5),
        ),
    ), 
}

def SetUp(file, orientation=landscape, units=inches):
    '''Convenience function to set up the drawing environment and return a
    file object to the output stream.
    '''
    ofp = open(file, "w")
    ginitialize(ofp, wrap_in_PJL)
    setOrientation(orientation, units)
    return ofp

def CardLabel(width, height, eye_distance_cm, text_height):
    push()
    translate(width/2, height/2)
    rotate(-90)
    move(0, text_height/2)
    ctext("%s cm eye-to-card distance" % eye_distance_cm)
    move(0, -text_height/2)
    push()
    textSize(0.75*text_height)
    textName(Sans)
    ctext("http://code.google.com/p/pygraphicsps")
    pop()
    pop()

def DegreeScale(tenth_degrees, eye_distance_cm, text_height):
    push()
    d = float(eye_distance_cm)*cm2in
    y0 = 0.08
    dx = 0.25
    translate(0, y0)
    move(0, 0)
    for theta in range(tenth_degrees + 1):
        y = 2*d*tan(theta/(10*2)*d2r)
        move(0, y)
        label = False
        if theta % 10 == 0:
            tick = dx
            label = True
        elif theta and theta % 5 == 0:
            tick = dx/1.25
        else:
            tick = dx/3
        rline(tick, 0)
        if label:
            move(dx*1.1, y - text_height/3.5)
            text("%d deg" % (theta/10))
    pop()

def TimesScale(marks, eye_distance_cm, text_height):
    '''marks is a list of tick marks:
        (factor, label_string, tick_lengths)
    where factor is a number, label_string is what to label the tick with,
    and tick_lengths is how many lengths to make the tick.

    Math:  1/factor is the ratio of the height to the distance.  Thus, the
    y distance plotted should be in the same ratio to the eye distance.
    '''
    push()
    d = float(eye_distance_cm)*cm2in
    y0 = 0.15
    dx = 0.1
    translate(0, y0)
    move(0, 0)
    rline(5*dx, 0)
    move(5*dx*1.05, -text_height/3.5)
    text("Ref")
    for factor, label, tick_length, text_height_factor in marks:
        y = d/factor
        move(0, y)
        x = tick_length*dx
        rline(x, 0)
        if label:
            move(2.5*dx, y - text_height/3.5)
            textSize(text_height*text_height_factor)
            text(label)
    pop()

def Card(x, y, marks, eye_distance_cm, width, height, tenth_degrees):
    push()
    translate(x*width, y*height)
    text_height = 0.14
    textSize(text_height)
    textName(SansBold)
    move(0, 0)
    rectangle(width, height)
    CardLabel(width, height, eye_distance_cm, text_height)
    DegreeScale(tenth_degrees, eye_distance_cm, text_height)
    translate(width, height)
    rotate(180)
    TimesScale(marks, eye_distance_cm, text_height)
    pop()

def main():
    f = SetUp(vd("out/bus_card_angle_measure.ps"))
    translate(1, 1)
    if debug:
        scale(2,2)
    width = 1.75
    height = 3.32
    for eye_dist in mark_dict:
        d = mark_dict[eye_dist]
        x, y = d[0]
        tenth_degrees, marks = d[1:]
        Card(x, y, marks, eye_dist, width, height, tenth_degrees)

main()
